home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
games
/
greversi
/
grevvs.lzh
/
src
/
main.s
< prev
next >
Wrap
Text File
|
2000-04-12
|
9KB
|
529 lines
;----------------------------------------------------------------
; greversi.x v0.14 (2000.02.04) by M.Kamada
; main.s メインルーチン
;----------------------------------------------------------------
.include doscall.mac
.include iocscall.mac
.include const.equ
;----------------------------------------------------------------
;バージョン
PROGNAME reg 'GREVERSI'
LOWER_PROGNAME reg 'greversi'
VERSION reg '0.15'
DATE reg '2000.04.11'
;----------------------------------------------------------------
;プログラム開始位置
.text
.align 4,$2048
prog_head::
;----------------------------------------------------------------
;実行開始位置
.text
.align 4,$2048
exec_entry:
lea.l (16,a0),a0
suba.l a0,a1
movem.l a0-a1,-(sp)
DOS _SETBLOCK
addq.l #8,d0
tst.l d0
bpl @f
pea.l (1f,pc)
DOS _PRINT
addq.l #4,sp
move.w #-1,-(sp)
DOS _EXIT2
1: .dc.b 'メモリが不足しています',13,10,0
.even
@@:
;----------------------------------------------------------------
;コマンドライン解析
lea.l stack_area,sp
bsr mysrand
sf.b extern_name
tst.b (a2)+
beq main_routine
movea.l a2,a1
10: lea.l temp,a0
bsr getword
bmi main_routine
beq error_exit
move.b (a0)+,d0
cmp.b #'-',d0
bne 40f
bra 30f
20: cmpi.b #' ',(a0)
bls 10b
30: moveq.l #$20,d0
or.b (a0)+,d0
9: cmp.b #'l',d0
bne 9f
bsr stou
bcs error_exit
cmp.w #1,d0
blo error_exit
cmp.w #5,d0
bhi error_exit
move.w d0,level
bra 20b
9: cmp.b #'m',d0
bne 9f
bsr stou
bcs error_exit
cmp.w #4,d0
bcc error_exit
move.w d0,mode
bra 20b
9: cmp.b #'q',d0
bne 9f
st.b quick_exec
bra 20b
9: cmp.b #'x',d0
bne 9f
tst.b (a0)
bne 1f
lea.l temp,a0
bsr getword
bmi error_exit
beq error_exit
1: bsr init_extern
bmi error_exit
bra 10b
9:
bra error_exit
40:
;----------------------------------------------------------------
;サブルーチンモード
; コマンドラインで指定された盤の状態と手番から次の1手を求め,
; 終了コードで返す
moveq.l #B,d6
moveq.l #W,d7
cmp.b #'0',d0
beq @f
exg.l d6,d7
cmp.b #'1',d0
bne error_exit
@@: tst.b (a0)
bne error_exit
lea.l temp,a0
bsr getword
lea.l ban+P11,a1
moveq.l #8-1,d2
2: moveq.l #8-1,d1
1: move.b (a0)+,d0
beq error_exit
moveq.l #B,d3
cmp.b #'0',d0
beq @f
moveq.l #W,d3
cmp.b #'1',d0
beq @f
moveq.l #S,d3
@@: move.b d3,(a1)+
dbra d1,1b
addq.l #1,a1
dbra d2,2b
lea.l put_list_top,a5 ;置ける位置のリストの先頭
lea.l put_record_btm,a6 ;レコードの末尾
bsr count_ban
beq error_exit ;どこにも置けない
move.w level,d0
bsr think
divu.w #9,d0
subq.w #1,d0 ;縦
move.w d0,d1
swap.w d0
subq.w #1,d0 ;横
lsl.w #3,d1
add.w d1,d0
move.w d0,-(sp)
DOS _EXIT2
;----------------------------------------------------------------
error_exit:
pea.l (m_errmes,pc)
DOS _PRINT
addq.l #4,sp
move.w #-1,-(sp)
DOS _EXIT2
m_errmes: .dc.b PROGNAME,'.X v',VERSION,' (',DATE,') by M.Kamada',13,10
.dc.b '使用法: ',LOWER_PROGNAME,' [スイッチ]',13,10
.dc.b 'スイッチ:',13,10
.dc.b ' -lN',9,'レベル(N=1~5,大きいほど強い)[1]',13,10
.dc.b ' -mN',9,'モード(N=0~3)[2]',13,10
.dc.b 9,'0=man-man,1=com-man,2=man-com,3=com-com',13,10
.dc.b 0
.even
.data
quick_exec: .dc.b 0
think_extern: .dc.b 0
extern_quick: .dc.b 0
.bss
temp: .ds.b 256
;----------------------------------------------------------------
;<a0.l:思考ルーチンの指定("greversi -l5"など)
.text
.even
init_extern:
movem.l d1-d7/a0-a6,-(sp)
movea.l a0,a1
lea.l extern_name,a0
bsr strcpy
clr.l -(sp)
pea.l extern_param
pea.l extern_name
move.w #2,-(sp)
DOS _EXEC
lea.l (14,sp),sp
tst.l d0
bmi 90f
.if 0
tst.b quick_exec
beq 10f
clr.w -(sp)
pea.l extern_name
DOS _OPEN
addq.l #6,sp
move.l d0,d1
bmi 10f
pea.l 64.w
pea.l extern_quick_header
move.w d1,-(sp)
DOS _READ
move.l d0,d2
DOS _CLOSE
addq.l #6,sp
cmp.l (sp)+,d2
bne 10f
lea.l extern_quick_header,a0
cmp.w #'HU',(a0)
bne 10f
move.l (12,a0),d0 ;text
add.l (16,a0),d0 ;data
add.l #240,d0 ;pdb
move.l d0,extern_quick_pdbtextdata
move.l (20,a0),d1 ;bss
move.l d1,extern_quick_bss
add.l d0,d1
move.l d1,extern_quick_size
move.l d0,-(sp)
move.w #2,-(sp)
DOS _MALLOC2
addq.l #6,sp
move.l d0,think_swap
bmi 10f
clr.l -(sp)
pea.l extern_param
pea.l extern_name
move.w #1,-(sp)
DOS _EXEC
lea.l (14,sp),sp
tst.l d0
bmi 90f
movem.l d0-d7/a0-a6,extern_quick_regs
lea.l (16,a0)
movem.l extern_quick_regs,d0-d7/a0-a6
lea.l (dummy_exit,pc),a4
move.l a4,-(sp)
move.w #4,-(sp)
DOS _EXEC
addq.l #6,sp
st.b extern_quick
10:
.endif
st.b think_extern
moveq.l #0,d0
99: movem.l (sp)+,d1-d7/a0-a6
rts
90: moveq.l #-1,d0
bra 99b
dummy_exit:
DOS _EXIT
.bss
extern_name: .ds.b 256
extern_param: .ds.b 256
.even
extern_quick_header: .ds.b 64
extern_quick_pdbtextdata: .ds.l 1
extern_quick_bss: .ds.l 1
extern_quick_size: .ds.l 1
extern_quick_regs: .ds.l 15
;----------------------------------------------------------------
.text
.even
exec_extern:
movem.l d1-d7/a0-a6,-(sp)
;コマンドラインを作る
lea.l extern_p+1,a0
lea.l extern_param+1,a1
bsr strcpy
move.b #' ',(a0)+
moveq.l #'0',d0
cmp.b #B,d6
beq @f
moveq.l #'1',d0
@@: move.b d0,(a0)+
move.b #' ',(a0)+
lea.l ban+P11,a1
moveq.l #8-1,d2
2: moveq.l #8-1,d1
1: move.b (a1)+,d3
moveq.l #'0',d0
cmp.b #B,d3
beq @f
moveq.l #'1',d0
cmp.b #W,d3
beq @f
moveq.l #'2',d0
@@: move.b d0,(a0)+
dbra d1,1b
addq.l #1,a1
dbra d2,2b
sf.b (a0)
move.l a0,d0
sub.l #extern_p+1,d0
move.b d0,extern_p
;
clr.l -(sp)
pea.l extern_p
pea.l extern_name
clr.w -(sp)
DOS _EXEC
lea.l (14,sp),sp
tst.l d0
bmi 90f
cmp.l #64,d0
bcc 90f
move.w d0,d1
lsr.w #3,d1
add.w d1,d0
add.w #10,d0
tst.l d0
99: movem.l (sp)+,d1-d7/a0-a6
rts
90: moveq.l #-1,d0
bra 99b
.if 0
move.l -8(a4),-(sp) *リミットアドレス
move.l a4,-(sp) *ロードアドレス
pea.l (filename)r *ファイル名
move.w #3,-(sp)
DOS _EXEC *実際に読み込む
lea.l 14(sp),sp
.endif
.bss
extern_p: .ds.b 256
;----------------------------------------------------------------
;メインルーチンモード
; 盤の状態を表示してゲームを行う
.text
.even
main_routine:
move.w #-1,-(sp)
DOS _BREAKCK
move.w d0,breakck_mode
move.w #1,-(sp) ;break on
DOS _BREAKCK
addq.l #2,sp
lea.l (main,pc),a0
bsr takeback
bsr tini_screen
move.w breakck_mode,-(sp)
bmi @f
DOS _BREAKCK
@@: addq.l #2,sp
DOS _EXIT
;----------------------------------------------------------------
;メインルーチン
main:
bsr init_screen
sf.b no_menu
game_loop:
bsr init_graph
bsr init_think
moveq.l #B,d6 ;自分の石
moveq.l #W,d7 ;相手の石
lea.l put_list_top,a5 ;置ける位置のリストの先頭
lea.l put_record_btm,a6 ;レコードの末尾
bsr draw_ban
bsr draw_black_count
bsr draw_white_count
clr.w turn_count
bsr draw_turn ;手番を表示する
tst.b no_menu
bne @f
bsr draw_menu
beq main_exit
@@:
main_loop:
DOS _KEYSNS
bsr count_ban
beq main_pass ;パス
bsr draw_turn ;手番を表示する
main_loop1:
move.w mode,d0
beq main_man
moveq.l #B,d1
subq.w #2,d0
blo @f
bhi main_com
moveq.l #W,d1
@@: cmp.b d1,d6
beq main_com
;人間の手番のときマウスで入力させる
main_man:
st.b turn_man
sf.b turn_com
@@: bsr input_pos
bmi main_menu
cmp.w #255,d0
beq @b ;盤の外
lea.l ban,a0
adda.l d0,a0
tst.b (a0)
bne @b ;石があるので置けない
bsr put_record_one ;石を置く
beq @b ;ひっくり返せないので置けない
bsr tup_draw ;表示する
bra main_next
main_menu:
@@: IOCS _MS_GETDT
tst.b d0
bne @b
bsr draw_menu
beq main_exit ;終了
bmi main_loop1 ;キャンセル
;対局
tst.w turn_count
beq main_loop1
st.b no_menu
bra game_loop
;コンピュータの手番のとき
main_com:
sf.b turn_man
st.b turn_com
IOCS _MS_GETDT
tst.b d0
bne main_menu
tst.b think_extern
bne 1f
move.w level,d0
bsr think
bra 2f
1: bsr exec_extern
bmi main_menu
2:
lea.l ban,a0
adda.l d0,a0
bsr put_record_one ;石を置く
beq main_menu
bsr tup_draw ;表示する
;相手の手番に移る
main_next:
exg.l d6,d7
addq.w #1,turn_count
bra main_loop
;パスのとき
main_pass:
;相手の手番に移る
exg.l d6,d7
bsr count_ban ;相手は置けるか
beq main_over ;両方ともパスなので終局
exg.l d6,d7
bsr draw_turn ;手番を表示する
bsr draw_pass
exg.l d6,d7
bra main_loop
;終局
main_over:
sf.b no_menu
bsr draw_over
bmi main_exit
move.w mode,d0
beq game_loop
cmp.w #3,d0
beq game_loop
eori.w #3,d0
move.w d0,mode
bra game_loop
main_exit:
rts
.data
.even
level:: .dc.w 1 ;1~5
mode:: .dc.w 2 ;0=man-man,1=com-man,2=man-com,3=com-com
breakck_mode: .dc.w -1 ;_BREAKCKの元のモード
.bss
turn_man:: .ds.b 1
turn_com:: .ds.b 1
no_menu: .ds.b 1 ;-1=ゲーム開始時にメニューを表示しない
.even
turn_count:: .ds.w 1 ;手番カウンタ(0=先攻の最初の1手)
.stack
.align 4
.ds.b 16384 ;スタックエリア
stack_area:
;----------------------------------------------------------------
.end exec_entry